using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MediPlatform.Domain.Order;
using MediPlatform.Infeartructure;
using MediPlatform.ErrorCode;

namespace MediPlatform.Write.Api.Controllers
{
    /// <summary>
    /// 问诊单写入控制器
    /// </summary>
    [ApiController]
    [Route("api/write/[controller]")]
    [Authorize]
    public class ConsultationWriteController : ControllerBase
    {
        private readonly IBaseRepository<ConsultationOrder> _consultationRepository;
        private readonly ILogger<ConsultationWriteController> _logger;

        public ConsultationWriteController(IBaseRepository<ConsultationOrder> consultationRepository, ILogger<ConsultationWriteController> logger)
        {
            _consultationRepository = consultationRepository;
            _logger = logger;
        }

        /// <summary>
        /// 创建问诊单
        /// </summary>
        /// <param name="request">问诊单创建请求</param>
        /// <returns>创建结果</returns>
        [HttpPost]
        public async Task<ApiResult<ConsultationOrder>> CreateConsultation([FromBody] CreateConsultationRequest request)
        {
            try
            {
                _logger.LogInformation("开始创建问诊单: {PatientId}", request.PatientId);

                // 生成订单号
                var orderNo = $"CO{DateTime.Now:yyyyMMddHHmmss}{Random.Shared.Next(1000, 9999)}";

                var consultation = new ConsultationOrder
                {
                    OrderNo = orderNo,
                    PatientId = request.PatientId,
                    DoctorId = request.DoctorId,
                    HospitalId = request.HospitalId,
                    DepartmentId = request.DepartmentId,
                    ConsultationType = request.ConsultationType,
                    Status = 1, // 待支付
                    AppointmentTime = request.AppointmentTime,
                    SubmitTime = DateTime.Now,
                    Fee = request.Fee,
                    DiscountAmount = request.DiscountAmount ?? 0,
                    ActualPayment = request.Fee - (request.DiscountAmount ?? 0),
                    ExtraInfo = request.ExtraInfo,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                };

                await _consultationRepository.AddAsync(consultation);
                await _consultationRepository.SaveChangesAsync();

                _logger.LogInformation("问诊单创建成功: {OrderNo}", orderNo);

                return ApiResult<ConsultationOrder>.Success(consultation, "问诊单创建成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建问诊单失败: {PatientId}", request.PatientId);
                return ApiResult<ConsultationOrder>.Error("创建问诊单失败");
            }
        }

        /// <summary>
        /// 更新问诊单状态
        /// </summary>
        /// <param name="orderNo">订单号</param>
        /// <param name="request">状态更新请求</param>
        /// <returns>更新结果</returns>
        [HttpPut("{orderNo}/status")]
        public async Task<ApiResult<ConsultationOrder>> UpdateConsultationStatus(string orderNo, [FromBody] UpdateStatusRequest request)
        {
            try
            {
                _logger.LogInformation("开始更新问诊单状态: {OrderNo} -> {Status}", orderNo, request.Status);

                var consultation = await _consultationRepository.GetAsync(c => c.OrderNo == orderNo);
                if (consultation == null)
                {
                    return ApiResult<ConsultationOrder>.Error("问诊单不存在");
                }

                // 检查权限：只有管理员、医生或患者本人可以更新状态
                var currentUserId = User.FindFirst("UserId")?.Value;
                var currentUserRole = User.FindFirst("role")?.Value;

                if (currentUserRole != "admin" && currentUserRole != "doctor" && 
                    consultation.PatientId.ToString() != currentUserId)
                {
                    return ApiResult<ConsultationOrder>.Error("无权限更新此问诊单");
                }

                consultation.Status = request.Status;
                consultation.UpdatedAt = DateTime.Now;

                // 根据状态更新相关时间
                switch (request.Status)
                {
                    case 2: // 已支付
                        consultation.PaymentTime = DateTime.Now;
                        consultation.PaymentMethod = request.PaymentMethod;
                        break;
                    case 3: // 已取消
                        consultation.CancelReason = request.CancelReason;
                        break;
                    case 4: // 已完成
                        // 可以添加完成时间等逻辑
                        break;
                }

                _consultationRepository.Update(consultation);
                await _consultationRepository.SaveChangesAsync();

                _logger.LogInformation("问诊单状态更新成功: {OrderNo} -> {Status}", orderNo, request.Status);

                return ApiResult<ConsultationOrder>.Success(consultation, "问诊单状态更新成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新问诊单状态失败: {OrderNo}", orderNo);
                return ApiResult<ConsultationOrder>.Error("更新问诊单状态失败");
            }
        }

        /// <summary>
        /// 取消问诊单
        /// </summary>
        /// <param name="orderNo">订单号</param>
        /// <param name="request">取消请求</param>
        /// <returns>取消结果</returns>
        [HttpPut("{orderNo}/cancel")]
        public async Task<ApiResult<ConsultationOrder>> CancelConsultation(string orderNo, [FromBody] CancelConsultationRequest request)
        {
            try
            {
                _logger.LogInformation("开始取消问诊单: {OrderNo}", orderNo);

                var consultation = await _consultationRepository.GetAsync(c => c.OrderNo == orderNo);
                if (consultation == null)
                {
                    return ApiResult<ConsultationOrder>.Error("问诊单不存在");
                }

                // 检查权限
                var currentUserId = User.FindFirst("UserId")?.Value;
                var currentUserRole = User.FindFirst("role")?.Value;

                if (currentUserRole != "admin" && currentUserRole != "doctor" && 
                    consultation.PatientId.ToString() != currentUserId)
                {
                    return ApiResult<ConsultationOrder>.Error("无权限取消此问诊单");
                }

                // 检查状态是否允许取消
                if (consultation.Status == 3 || consultation.Status == 4)
                {
                    return ApiResult<ConsultationOrder>.Error("问诊单状态不允许取消");
                }

                consultation.Status = 3; // 已取消
                consultation.CancelReason = request.Reason;
                consultation.UpdatedAt = DateTime.Now;

                // 如果已支付，计算退款金额
                if (consultation.PaymentTime.HasValue)
                {
                    consultation.RefundAmount = consultation.ActualPayment;
                    consultation.RefundTime = DateTime.Now;
                }

                _consultationRepository.Update(consultation);
                await _consultationRepository.SaveChangesAsync();

                _logger.LogInformation("问诊单取消成功: {OrderNo}", orderNo);

                return ApiResult<ConsultationOrder>.Success(consultation, "问诊单取消成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "取消问诊单失败: {OrderNo}", orderNo);
                return ApiResult<ConsultationOrder>.Error("取消问诊单失败");
            }
        }

        /// <summary>
        /// 删除问诊单（仅管理员）
        /// </summary>
        /// <param name="orderNo">订单号</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{orderNo}")]
        [Authorize(Roles = "admin")]
        public async Task<ApiResult<bool>> DeleteConsultation(string orderNo)
        {
            try
            {
                _logger.LogInformation("开始删除问诊单: {OrderNo}", orderNo);

                var consultation = await _consultationRepository.GetAsync(c => c.OrderNo == orderNo);
                if (consultation == null)
                {
                    return ApiResult<bool>.Error("问诊单不存在");
                }

                _consultationRepository.Delete(consultation);
                await _consultationRepository.SaveChangesAsync();

                _logger.LogInformation("问诊单删除成功: {OrderNo}", orderNo);

                return ApiResult<bool>.Success(true, "问诊单删除成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除问诊单失败: {OrderNo}", orderNo);
                return ApiResult<bool>.Error("删除问诊单失败");
            }
        }
    }

    /// <summary>
    /// 创建问诊单请求模型
    /// </summary>
    public class CreateConsultationRequest
    {
        /// <summary>
        /// 患者ID
        /// </summary>
        public long PatientId { get; set; }

        /// <summary>
        /// 医生ID
        /// </summary>
        public long DoctorId { get; set; }

        /// <summary>
        /// 医院ID
        /// </summary>
        public long HospitalId { get; set; }

        /// <summary>
        /// 科室ID
        /// </summary>
        public long DepartmentId { get; set; }

        /// <summary>
        /// 问诊类型
        /// </summary>
        public int ConsultationType { get; set; }

        /// <summary>
        /// 预约时间
        /// </summary>
        public DateTime AppointmentTime { get; set; }

        /// <summary>
        /// 费用
        /// </summary>
        public decimal Fee { get; set; }

        /// <summary>
        /// 折扣金额
        /// </summary>
        public decimal? DiscountAmount { get; set; }

        /// <summary>
        /// 额外信息
        /// </summary>
        public string? ExtraInfo { get; set; }
    }

    /// <summary>
    /// 更新状态请求模型
    /// </summary>
    public class UpdateStatusRequest
    {
        /// <summary>
        /// 新状态
        /// </summary>
        public int Status { get; set; }

        /// <summary>
        /// 支付方式
        /// </summary>
        public string? PaymentMethod { get; set; }

        /// <summary>
        /// 取消原因
        /// </summary>
        public string? CancelReason { get; set; }
    }

    /// <summary>
    /// 取消问诊单请求模型
    /// </summary>
    public class CancelConsultationRequest
    {
        /// <summary>
        /// 取消原因
        /// </summary>
        public string Reason { get; set; } = string.Empty;
    }
} 